// DataCache for 1.20
//
library DataCache initializer init requires ListModule

function GetHandleId takes handle h returns integer
    return h
    return 0
endfunction

function StringHash takes string s returns integer
    return s
    return 0
endfunction

function GetSpellTargetX takes nothing returns real
    local location loc = GetSpellTargetLoc()
    local real x = GetLocationX(loc)
    call RemoveLocation(loc)
    set loc = null
    return x
endfunction

function GetSpellTargetY takes nothing returns real
    local location loc = GetSpellTargetLoc()
    local real y = GetLocationY(loc)
    call RemoveLocation(loc)
    set loc = null
    return y
endfunction

//! textmacro LoadConvertValues takes NAME, TYPE
function I2$NAME$ takes integer i returns $TYPE$
    return i
    return null
endfunction
//! endtextmacro

//! runtextmacro LoadConvertValues("Unit", "unit")
//! runtextmacro LoadConvertValues("Timer", "timer")
//! runtextmacro LoadConvertValues("Trigger", "trigger")
//! runtextmacro LoadConvertValues("Boolexpr", "boolexpr")
//! runtextmacro LoadConvertValues("Region", "region")
//! runtextmacro LoadConvertValues("Rect", "rect")
//! runtextmacro LoadConvertValues("Sound", "sound")

struct DataCache
    public gamecache m_gc = null

    public string m_key

    implement StructList

    static method get takes string pkey returns DataCache
        local DataCache d = DataCache.first
        loop
            exitwhen d <= 0
            if d.m_key == pkey then
                return d
            endif
            set d = d.next
        endloop
        return 0
    endmethod

    static method create takes string pkey returns DataCache
        local DataCache this =  DataCache.get(pkey)
        if (this > 0) then
            return this
        endif
        set this = DataCache.allocate()
        set this.m_gc = InitGameCache(pkey + ".w3v")
        call this.listAdd()
        return this
    endmethod

    method destroy takes nothing returns nothing
        call this.listRemove()
        call this.deallocate()
    endmethod

    method saveInteger takes integer parentKey, integer childKey, integer value returns nothing
        call StoreInteger(this.m_gc, I2S(parentKey), I2S(childKey), value)
    endmethod

    method loadInteger takes integer parentKey, integer childKey returns integer
        return GetStoredInteger(this.m_gc, I2S(parentKey), I2S(childKey))
    endmethod

    method haveSavedInteger takes integer parentKey, integer childKey returns boolean
        return HaveStoredInteger(this.m_gc, I2S(parentKey), I2S(childKey))
    endmethod

    method removeSavedInteger takes integer parentKey, integer childKey returns nothing
        call FlushStoredInteger(this.m_gc, I2S(parentKey), I2S(childKey))
    endmethod

    // real
    method saveReal takes integer parentKey, integer childKey, real value returns nothing
        call StoreReal(this.m_gc, I2S(parentKey), I2S(childKey), value)
    endmethod

    method loadReal takes integer parentKey, integer childKey returns real
        return GetStoredReal(this.m_gc, I2S(parentKey), I2S(childKey))
    endmethod

    method haveSavedReal takes integer parentKey, integer childKey returns boolean
        return HaveStoredReal(this.m_gc, I2S(parentKey), I2S(childKey))
    endmethod

    method removeSavedReal takes integer parentKey, integer childKey returns nothing
        call FlushStoredReal(this.m_gc, I2S(parentKey), I2S(childKey))
    endmethod

    // boolexpr
    method saveBooleanExprHandle takes integer parentKey, integer childKey, boolexpr value returns nothing
        call saveInteger(parentKey, childKey, GetHandleId(value))
    endmethod

    method loadBooleanExprHandle takes integer parentKey, integer childKey returns boolexpr
        return I2Boolexpr(loadInteger(parentKey, childKey))
    endmethod

    // region
    method saveRegionHandle takes integer parentKey, integer childKey, region value returns nothing
        call saveInteger(parentKey, childKey, GetHandleId(value))
    endmethod

    method loadRegionHandle takes integer parentKey, integer childKey returns region
        return I2Region(loadInteger(parentKey, childKey))
    endmethod

    // rect
    method saveRectHandle takes integer parentKey, integer childKey, rect value returns nothing
        call saveInteger(parentKey, childKey, GetHandleId(value))
    endmethod

    method loadRectHandle takes integer parentKey, integer childKey returns rect
        return I2Rect(loadInteger(parentKey, childKey))
    endmethod

    // sound
    method saveSoundHandle takes integer parentKey, integer childKey, sound value returns nothing
        call saveInteger(parentKey, childKey, GetHandleId(value))
    endmethod

    method loadSoundHandle takes integer parentKey, integer childKey returns sound
        return I2Sound(loadInteger(parentKey, childKey))
    endmethod

    // common
    method haveSavedHandle takes integer parentKey, integer childKey returns boolean
        return haveSavedInteger(parentKey, childKey)
    endmethod

    method removeSavedHandle takes integer parentKey, integer childKey returns nothing
        call removeSavedInteger(parentKey, childKey)
    endmethod

    method flush takes integer parentKey returns nothing
        call FlushStoredMission(this.m_gc, I2S(parentKey))
    endmethod

endstruct

function init takes nothing returns nothing

endfunction

endlibrary
